


/* > time list */

#ifndef _TLIST_H_
#define _TLIST_H_

#ifdef __cplusplus
extern "C"
{
#endif

//#include "IncludeAll.h"
#include "types.h"
#include "macdef.h"

/*! OS define */
typedef uint16 BaseType_t;
typedef uint16 UBaseType_t;
typedef uint16 TickType_t;
#define  pdFALSE false 
#define  pdTRUE  true	
#define  portMAX_DELAY 0xFFFF

#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))

/* 不需要检查列表完整性 */
//@ #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
//@ #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
//@ #define listFIRST_LIST_INTEGRITY_CHECK_VALUE
//@ #define listSECOND_LIST_INTEGRITY_CHECK_VALUE
//@ #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
//@ #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
//@ #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )
//@ #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
//@ #define listTEST_LIST_ITEM_INTEGRITY( pxItem )
//@ #define listTEST_LIST_INTEGRITY( pxList )

/*! ---------- 链表结构定义 ---------- */

//#pragma pack(8)
/*
	* Definition of the only type of object that a list can contain.
	*/
struct xLIST;
struct xLIST_ITEM
{
	/*! 此处要特别注意，迷你'MiniList'和 list 相同参数配列一致才行，因为链表操作中有互相转换的操作 */
	
     TickType_t xItemValue;			/*< The value being listed.  In most cases this is used to sort the list in descending order. */
	//@ listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE			/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
	struct xLIST_ITEM*  pxNext;		/*< Pointer to the next ListItem_t in the list. */
	struct xLIST_ITEM*  pxPrevious;	/*< Pointer to the previous ListItem_t in the list. */

	void* pvOwner;

	/*! 这个值用于记录自己属于哪个列表，删除的时候，不用导入链表名，只要输入节点即可 */
	struct xLIST*  pxContainer;		/*< Pointer to the list in which this list item is placed (if any). */

	//@ listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE			/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
};
//#pragma pack()
typedef struct xLIST_ITEM ListItem_t;					/* For some reason lint wants this as two separate definitions. */

/*! 将‘xMINI_LIST_ITEM’删除，这样头列表就不会使用 mini 对象作头节点，类型转换可以正常。 */
struct xMINI_LIST_ITEM
{
	//@ listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE			/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
		   TickType_t xItemValue;
	struct xLIST_ITEM*  pxNext;
	struct xLIST_ITEM*  pxPrevious;

};
typedef struct xMINI_LIST_ITEM MiniListItem_t;

/*
	* Definition of the type of queue used by the scheduler.
	*/
typedef struct xLIST
{
	//@ listFIRST_LIST_INTEGRITY_CHECK_VALUE				/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
		volatile UBaseType_t uxNumberOfItems;
	ListItem_t*  pxIndex;			/*< Used to walk through the list.  Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
	MiniListItem_t xListEnd;							/*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
	//@ listSECOND_LIST_INTEGRITY_CHECK_VALUE				/*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
} List_t;


/*! ---------- 链表函数定义！----------  */
/*
 * Access macro to set the owner of a list item.  The owner of a list item
 * is the object (usually a TCB) that contains the list item.
 *
 * page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
 * ingroup LinkedList
 */
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner )		( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )

 /*
  * Access macro to get the owner of a list item.  The owner of a list item
  * is the object (usually a TCB) that contains the list item.
  *
  * page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
  * ingroup LinkedList
  */
#define listGET_LIST_ITEM_OWNER( pxListItem )	( ( pxListItem )->pvOwner )

  /*
   * Access macro to set the value of the list item.  In most cases the value is
   * used to sort the list in descending order.
   *
   * page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
   * ingroup LinkedList
   */
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue )	( ( pxListItem )->xItemValue = ( xValue ) )

   /*
	* Access macro to retrieve the value of the list item.  The value can
	* represent anything - for example the priority of a task, or the time at
	* which a task should be unblocked.
	*
	* page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
	* ingroup LinkedList
	*/
/*! 索引指针，索引指针最初位置应该在根节点处，也就是xListEnd处，便于对链表进行遍历和处理*/
#define listGET_LIST_ITEM_VALUE( pxListItem )	( ( pxListItem )->xItemValue )

	/*
	 * Access macro to retrieve the value of the list item at the head of a given
	 * list.
	 *
	 * page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
	 * ingroup LinkedList
	 */
/*! 索引指针，索引指针最初位置应该在根节点处，也就是xListEnd处，便于对链表进行遍历和处理*/
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList )	( ( ( pxList )->xListEnd ).pxNext->xItemValue )

	 /*
	  * Return the list item at the head of the list.
	  *
	  * page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
	  * ingroup LinkedList
	  */
#define listGET_HEAD_ENTRY( pxList )	( ( ( pxList )->xListEnd ).pxNext )

	  /*
	   * Return the list item at the head of the list.
	   *
	   * page listGET_NEXT listGET_NEXT
	   * ingroup LinkedList
	   */
#define listGET_NEXT( pxListItem )	( ( pxListItem )->pxNext )

	   /*
		* Return the list item that marks the end of the list
		*
		* page listGET_END_MARKER listGET_END_MARKER
		* ingroup LinkedList
		*/
#define listGET_END_MARKER( pxList )	( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )

		/*
		 * Access macro to determine if a list contains any items.  The macro will
		 * only have the value true if the list is empty.
		 *
		 * page listLIST_IS_EMPTY listLIST_IS_EMPTY
		 * ingroup LinkedList
		 */
#define listLIST_IS_EMPTY( pxList )	( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )

		 /*
		  * Access macro to return the number of items in the list.
		  */
#define listCURRENT_LIST_LENGTH( pxList )	( ( pxList )->uxNumberOfItems )

		  /*
		   * Access function to obtain the owner of the next entry in a list.
		   *
		   * The list member pxIndex is used to walk through a list.  Calling
		   * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
		   * and returns that entry's pxOwner parameter.  Using multiple calls to this
		   * function it is therefore possible to move through every item contained in
		   * a list.
		   *
		   * The pxOwner parameter of a list item is a pointer to the object that owns
		   * the list item.  In the scheduler this is normally a task control block.
		   * The pxOwner parameter effectively creates a two way link between the list
		   * item and its owner.
		   *
		   * @param pxTCB pxTCB is set to the address of the owner of the next list item.
		   * @param pxList The list from which the next item owner is to be returned.
		   *
		   * page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
		   * ingroup LinkedList
		   */
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )										\
{																							\
List_t * const pxConstList = ( pxList );													\
	/* Increment the index to the next item and return the item, ensuring */				\
	/* we don't return the marker used at the end of the list.  */							\
	( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;							\
	if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )	\
	{																						\
		( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;						\
	}																						\
	( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;											\
}


		   /*
			* Access function to obtain the owner of the first entry in a list.  Lists
			* are normally sorted in ascending item value order.
			*
			* This function returns the pxOwner member of the first item in the list.
			* The pxOwner parameter of a list item is a pointer to the object that owns
			* the list item.  In the scheduler this is normally a task control block.
			* The pxOwner parameter effectively creates a two way link between the list
			* item and its owner.
			*
			* @param pxList The list from which the owner of the head item is to be
			* returned.
			*
			* page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
			* ingroup LinkedList
			*/
#define listGET_OWNER_OF_HEAD_ENTRY( pxList )  ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )

			/*
			 * Check to see if a list item is within a list.  The list item maintains a
			 * "container" pointer that points to the list it is in.  All this macro does
			 * is check to see if the container and the list match.
			 *
			 * @param pxList The list we want to know if the list item is within.
			 * @param pxListItem The list item we want to know if is in the list.
			 * @return pdTRUE if the list item is in the list, otherwise pdFALSE.
			 */
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) )

			 /*
			  * Return the list a list item is contained within (referenced from).
			  *
			  * @param pxListItem The list item being queried.
			  * @return A pointer to the List_t object that references the pxListItem
			  */
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer )

			  /*
			   * This provides a crude means of knowing if a list has been initialised, as
			   * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()
			   * function.
			   */
#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )

			   /*
				* Must be called before a list is used!  This initialises all the members
				* of the list structure and inserts the xListEnd item into the list as a
				* marker to the back of the list.
				*
				* @param pxList Pointer to the list being initialised.
				*
				* page vListInitialise vListInitialise
				* ingroup LinkedList
				*/
void vListInitialise(List_t* const pxList) ;

/*
 * Must be called before a list item is used.  This sets the list container to
 * null so the item does not think that it is already contained in a list.
 *
 * @param pxItem Pointer to the list item being initialised.
 *
 * page vListInitialiseItem vListInitialiseItem
 * ingroup LinkedList
 */
void vListInitialiseItem(ListItem_t* const pxItem) ;

/*
 * Insert a list item into a list.  The item will be inserted into the list in
 * a position determined by its item value (descending item value order).
 *
 * @param pxList The list into which the item is to be inserted.
 *
 * @param pxNewListItem The item that is to be placed in the list.
 *
 * page vListInsert vListInsert
 * ingroup LinkedList
 */
void vListInsert(List_t* const pxList, ListItem_t* const pxNewListItem) ;

/*
 * Insert a list item into a list.  The item will be inserted in a position
 * such that it will be the last item within the list returned by multiple
 * calls to listGET_OWNER_OF_NEXT_ENTRY.
 *
 * The list member pxIndex is used to walk through a list.  Calling
 * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
 * Placing an item in a list using vListInsertEnd effectively places the item
 * in the list position pointed to by pxIndex.  This means that every other
 * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
 * the pxIndex parameter again points to the item being inserted.
 *
 * @param pxList The list into which the item is to be inserted.
 *
 * @param pxNewListItem The list item to be inserted into the list.
 *
 * page vListInsertEnd vListInsertEnd
 * ingroup LinkedList
 */
void vListInsertEnd(List_t* const pxList, ListItem_t* const pxNewListItem) ;

/*
 * Remove an item from a list.  The list item has a pointer to the list that
 * it is in, so only the list item need be passed into the function.
 *
 * @param uxListRemove The item to be removed.  The item will remove itself from
 * the list pointed to by it's pxContainer parameter.
 *
 * @return The number of items that remain in the list after the list item has
 * been removed.
 *
 * page uxListRemove uxListRemove
 * ingroup LinkedList
 */
UBaseType_t uxListRemove(ListItem_t* const pxItemToRemove);


#ifdef __cplusplus
}
#endif

#endif /* endif */


























